package com.lyf.scm.plan.domain.service.impl;

import com.lyf.scm.common.enums.OtherTargetsEnum;
import com.lyf.scm.common.enums.SkuUnitTypeEnum;
import com.lyf.scm.plan.api.dto.OtherTargetEchartResultDTO;
import com.lyf.scm.plan.api.dto.OtherTargetGeneralQueryDTO;
import com.lyf.scm.plan.api.dto.OtherTargetResultDTO;
import com.lyf.scm.plan.domain.remote.stock.dto.QueryRealTimeStockDTO;
import com.lyf.scm.plan.domain.remote.stock.dto.RealTimeStockDTO;
import com.lyf.scm.plan.domain.service.CommonService;
import com.lyf.scm.plan.domain.service.RealTimeStockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * description:
 * 实时库存
 *
 * @author: haodong
 * @data: 2020/11/20 11:38
 */
@Slf4j
@Service
public class RealTimeStockServiceImpl implements RealTimeStockService {

    @Resource
    private CommonService commonService;

    /**
     * 获取列表结果
     *
     * @param otherTargetQuery
     * @return {@link OtherTargetResultDTO}
     **/
    @Override
    public OtherTargetResultDTO getResult(OtherTargetGeneralQueryDTO otherTargetQuery, Map<String, BigDecimal> unitMap) {
        Map<String, List<BigDecimal>> map = this.getRealTimeStock(this.getQuery(otherTargetQuery), otherTargetQuery.getDateList(), unitMap, otherTargetQuery.getUnitType());
        OtherTargetResultDTO otherTargetResultDTO = new OtherTargetResultDTO();
        otherTargetResultDTO.setOtherTargetsEnum(OtherTargetsEnum.REAL_TIME_STOCK);
        otherTargetResultDTO.setResult(map);
        return otherTargetResultDTO;
    }

    @Override
    public List<OtherTargetResultDTO> getBatchResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO, Map<String, BigDecimal> unitMap) {
        return null;
    }

    /**
     * 获取图表结果
     *
     * @param otherTargetQuery
     * @return {@link OtherTargetEchartResultDTO}
     **/
    @Override
    public OtherTargetEchartResultDTO getEchartResult(OtherTargetGeneralQueryDTO otherTargetQuery) {
        OtherTargetEchartResultDTO otherTargetEchartResultDTO = new OtherTargetEchartResultDTO();
        otherTargetEchartResultDTO.setOtherTargetsEnum(OtherTargetsEnum.REAL_TIME_STOCK);
        List<BigDecimal> list = this.getEchartRealTimeStock(this.getQuery(otherTargetQuery), otherTargetQuery.getDateList());
        otherTargetEchartResultDTO.setResult(list);
        return otherTargetEchartResultDTO;
    }

    @Override
    public List<OtherTargetEchartResultDTO> getBatchEchartResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO) {
        return null;
    }

    private QueryRealTimeStockDTO getQuery(OtherTargetGeneralQueryDTO queryData) {
        QueryRealTimeStockDTO realTimeStock = new QueryRealTimeStockDTO();
        realTimeStock.setBusinessType(queryData.getBusinessType());
        realTimeStock.setCodeList(queryData.getDeliverIds());
        if (CollectionUtils.isNotEmpty(queryData.getSkuList())) {
            realTimeStock.setSkuCodeList(queryData.getSkuList());
        }
        return realTimeStock;
    }

    public Map<String, List<BigDecimal>> getRealTimeStock(QueryRealTimeStockDTO queryData, List<String> dateList, Map<String, BigDecimal> unitMap, Long unitType) {
        return parsingData(commonService.listAvailableQty(queryData), dateList, unitMap, unitType);
    }

    @Override
    public List<BigDecimal> getEchartRealTimeStock(QueryRealTimeStockDTO query, List<String> dateList) {
        return parsingEchartData(commonService.listAvailableQty(query), dateList);
    }

    private List<BigDecimal> parsingEchartData(List<RealTimeStockDTO> listAvailableQty, List<String> dateList) {
        List<BigDecimal> resultList = new ArrayList<>();
        BigDecimal availableQty = listAvailableQty.stream().filter(e -> e.getAvailableQty() != null)
                .map(RealTimeStockDTO::getAvailableQty).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        String monday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY).toLocalDate().toString();
        dateList.forEach(v -> resultList.add(v.equals(monday) ? availableQty : BigDecimal.ZERO));
        return resultList;
    }

    private Map<String, List<BigDecimal>> parsingData(List<RealTimeStockDTO> listAvailableQty, List<String> dateList, Map<String, BigDecimal> unitMap, Long unitType) {
        Map<String, List<BigDecimal>> result = new HashMap<>();
        for (RealTimeStockDTO realTimeStock : listAvailableQty) {
            String unitKey = realTimeStock.getSkuCode() + SkuUnitTypeEnum.BASIS_UNIT.getUnitType() + unitType;
            String key = realTimeStock.getFactoryCode() + realTimeStock.getSkuCode();
            String monday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY).toLocalDate().toString();
            List<BigDecimal> targetList = dateList.stream()
                    .map(item -> {
                                if (item.equals(monday)) {
                                    if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(unitType)) {
                                        return realTimeStock.getAvailableQty().multiply(unitMap.get(unitKey)).setScale(3,BigDecimal.ROUND_HALF_UP);
                                    } else {
                                        return realTimeStock.getAvailableQty();
                                    }
                                } else {
                                    return BigDecimal.ZERO;
                                }
                            }
                    ).collect(Collectors.toList());
            result.put(key, targetList);
        }
        return result;
    }
}
